Copyright (c) 1999 Massachusetts Institute of Technology

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, see https://gnu.org/licenses or write
to:
  Free Software Foundation, Inc.
  51 Franklin Street, Fifth Floor
  Boston, MA 02110-1301
  USA
------------------------------


SUBTTL I/O DEVICE DISPATCH TABLES

COMMENT |
	This page tries to document the ITS I/O device dispatch tables and
dispatch environment.  It is not completed yet.

The tables use several different indices, which are:
	opnidx - result of device name lookup in DEVTAB
	ioidx  - result of OPEN; has symbolic values.  This is the index
		stored in RH of IOCHNM (per-job channel table)
	sidx  - secondary index from DCHSTB(ioidx)
	ridx  - secondary index from RSTB(ioidx)

The following system calls are dispatched through these tables.
There are 11 dispatch routines that each device must specify.
The format is "CALL [table name(index-used) -> device-routine]"
Unless otherwise noted, context for all routines has
	U/ User index
	R/ addr of IOCHNM word for specified channel
and the phrase "all ACs can be used" excludes P and U, of course.
and routines can hang (u.o.n.)

OPEN [DEVADR(opnidx) -> devO]
	"opnidx" is looked up from DEVTAB which holds the device names.
	The device's OPEN routine is in the RH of DEVADR.
	It must set up the user's IOCHNM word for the channel,
	by setting the RH to the right "ioidx" and the LH to whatever
	the device wants.

	Context:
		A/ FN1
		B/ FN2
		C/ <mode bits>,,<device name>
		D/ <mode bits rotated -1>
		E/ <device name>
		TT/ DEVADR word <bits>,,<routine>
		W/ "open" command (0= Normal R/W open, 1= Write-over mode,
			2= Make link, 4= Delete or rename)
		SRN3(U),SRN4(U),SRN5(U) - args 4,5,6 (if present)

	Routine is JRST'd to, and must return via POPJ1 for success.
	Errors should JRST to the appropriate OPNLnn label.
	All ACs can be smashed.

CLOSE [CLSTB(ioidx) -> devCLS]
	The device's CLOSE routine is in the RH of CLSTB.

	Context:
		A/ 0,,<LH of IOCHNM word>
		B/ 0,,<RH of IOCHNM word>
		C/ CLSTB entry, <bits>,,<rtn addr>
		R/ addr of IOCHNM word
	Called via PUSHJ, must return via POPJ (IOCHNM and IOCHST will
	be cleared immediately after return).
	Can smash all ACs including R.
	Must NOT hang!

IOT, SIOT [IOTTB(ioidx) -> devVarious]
	These routines do I/O transfers.  The main reason "ioidx"
	has so many possible values (causing IOTTB to be large) is
	because lots of devices specify different ioidx's for different
	modes - input/output, block/unit, image/ascii, etc - in order
	to speed up actual I/O transfers, which are probably the most
	common device-related system calls.

	Context:
		Boy is this complicated.

STATUS	[LH(DSTSTB(sidx)) -> devSTA]
	Context:
		R/ addr of IOCHNM word
	Called by PUSHJ, must return by POPJ
	Must return in RH(D) some device-dependent status stuff.
	Calling routine (NSTATUS) fills in the LH from IOCHST.
	Must not smash C,R!  Probably should not smash other
	stuff either, depending on what USRVAR/USET need.

WHYINT	[RH(DSTSTB(sidx)) -> devWHY]

RCHST, RFNAME	[LH(DRFNTB(sidx)) -> devRCH]

RFPNTR	[RH(DRFNTB(sidx)) -> devRFP]

IOPUSH, IOPOP	[LH(RSTB1(ridx)) -> devIOP]

RESET	[RH(RSTB1(ridx)) -> devRST]
	Context:
		R/ addr of IOCHNM wd
	Called by JRST from NRESET/ARESET/AIOPP1, must return by POPJ.
	Can clobber all ACs.  Must not hang.

FORCE	[LH(DFRCTB(ridx)) -> devFRC]
	Context:
		A/ LH of IOCHNM word, in RH.
		H/ IOCHNM word
		R/ <LH of CLSTB entry>,,<addr of IOCHNM word>
	Called by JRST from NFORCE.  Returns by POPJ1 for win,
	POPJ if fail.  Should not clobber context that FINISH routine
	may need.

FINISH	[RH(DFRCTB(ridx)) -> devFIN]
	Same as FORCE, except that FORCE is called first, thus
	context is whatever FORCE leaves behind.  This routine
	must do the actual waiting for FORCE's actions to be
	finished.

|
